home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir31 / vtsrc12b.zip / LIB / SWAPMANA.PAS < prev    next >
Pascal/Delphi Source File  |  1993-02-12  |  13KB  |  519 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         SwapManager                                                }
  4. {                                                                            }
  5. { DESCRIPTION:    This UNIT implements a swapping manager. The Swapping is   }
  6. {                 made to a Turbo Vision Stream. Any stream can be used, but }
  7. {                 it's recommended to use the TSwapStream found in the       }
  8. {                 SwapStream UNIT.                                           }
  9. {                                                                            }
  10. {                 The manager works much like a dynamic memory manager, but  }
  11. {                 uses handles instead of pointers. Handles MUST be          }
  12. {                 initialized by calling the Init constructor, and           }
  13. {                 uninitialized by calling the Done destructor. The handle   }
  14. {                 methods provide access to all the swapping services.       }
  15. {                                                                            }
  16. {                 The recommended method of usage is the following:          }
  17. {                                                                            }
  18. {                 (* ---------------------------------------------------- *) }
  19. {                                                                            }
  20. {                 VAR                                                        }
  21. {                   Handle : TSwapHandle;                                    }
  22. {                                                                            }
  23. {                 ...                                                        }
  24. {                                                                            }
  25. {                 Handle.Init;                (* Initialize Handle *)        }
  26. {                                                                            }
  27. {                 ...                                                        }
  28. {                                                                            }
  29. {                 Handle.Write(Buffer, Size); (* Save buffer in swap stream*)}
  30. {                                                                            }
  31. {                 ...                                                        }
  32. {                                                                            }
  33. {                 Handle.Read(Buffer, Size);  (* Retrieve saved buffer *)    }
  34. {                 Handle.Free;                (* If not needed any more *)   }
  35. {                 ...                                                        }
  36. {                                                                            }
  37. {                 Handle.Done;                (* Uninitialize Handle *)      }
  38. {                                                                            }
  39. {                 (* ---------------------------------------------------- *) }
  40. {                                                                            }
  41. { AUTHOR:         Juan Carlos Arévalo                                        }
  42. {                                                                            }
  43. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  44. {                                                                            }
  45. { HISTORY:        17-Jan-1993 Definition and implementation.                 }
  46. {                             Including cleanup methods.                     }
  47. {                                                                            }
  48. { (C) 1993 VangeliSTeam                                                      }
  49. {____________________________________________________________________________}
  50.  
  51. UNIT SwapManager;
  52.  
  53. INTERFACE
  54.  
  55. USES Objects;
  56.  
  57.  
  58.  
  59.  
  60. { Cleanup action needed. }
  61.  
  62. TYPE
  63.   TClAction = (cluNone, cluFast, cluFull);
  64.  
  65.  
  66.  
  67.  
  68. { TSwapHandle object. }
  69.  
  70. TYPE
  71.   PSwapHandle = ^TSwapHandle;
  72.   TSwapHandle =
  73.     OBJECT
  74.       Pos    : LONGINT;
  75.       Size   : WORD;
  76.       Status : WORD;
  77.       Next   : PSwapHandle;
  78.       Prev   : PSwapHandle;
  79.  
  80.       CONSTRUCTOR Init;
  81.       DESTRUCTOR  Done;                                     VIRTUAL;
  82.       PROCEDURE   Error ( AStatus: WORD );                  VIRTUAL;
  83.  
  84.       FUNCTION  Write ( VAR Buf; ASize: WORD ) : BOOLEAN;   VIRTUAL;
  85.       FUNCTION  Read  ( VAR Buf; ASize: WORD ) : BOOLEAN;   VIRTUAL;
  86.       PROCEDURE Free;                                       VIRTUAL;
  87.  
  88.       PROCEDURE Link;                                       VIRTUAL;
  89.       PROCEDURE Unlink;                                     VIRTUAL;
  90.       PROCEDURE MoveFrom   (OPos: LONGINT);                 VIRTUAL;
  91.       FUNCTION  NeedCleanup                : TClAction;     VIRTUAL;
  92.       PROCEDURE FastCleanup;                                VIRTUAL;
  93.       PROCEDURE FullCleanup;                                VIRTUAL;
  94.       PROCEDURE Shrink;                                     VIRTUAL;
  95.  
  96.       FUNCTION UsedMem   : LONGINT;                         VIRTUAL;
  97.       FUNCTION UnusedMem : LONGINT;                         VIRTUAL;
  98.       FUNCTION TotalSize : LONGINT;                         VIRTUAL;
  99.     END;
  100.  
  101.  
  102.  
  103.  
  104. { Swapper initialization and uninitialization. }
  105.  
  106. FUNCTION  InitSwapManager(St: PStream) : BOOLEAN;
  107. PROCEDURE DoneSwapManager;
  108.  
  109.  
  110.  
  111.  
  112. IMPLEMENTATION
  113.  
  114. USES Heaps;
  115.  
  116.  
  117.  
  118.  
  119.  
  120. {----------------------------------------------------------------------------}
  121. { Swapper variables.                                                         }
  122. {____________________________________________________________________________}
  123.  
  124. CONST
  125.   HandleListHead : PSwapHandle = NIL;
  126.   HandleListTail : PSwapHandle = NIL;
  127.  
  128.   SwapFile      : PStream = NIL;
  129.   SwapFileValid : BOOLEAN = FALSE;
  130.  
  131.  
  132.  
  133.  
  134. {----------------------------------------------------------------------------}
  135. { Initialization and uninitialization routine.                               }
  136. {____________________________________________________________________________}
  137.  
  138. FUNCTION InitSwapManager(St: PStream) : BOOLEAN;
  139.   BEGIN
  140.     IF SwapFile <> NIL THEN
  141.       DoneSwapManager;
  142.  
  143.     HandleListHead := NIL;
  144.     HandleListTail := NIL;
  145.  
  146.     SwapFile := St;
  147.  
  148.     SwapFileValid   := (SwapFile <> NIL) AND (SwapFile^.Status = stOk);
  149.     InitSwapManager := SwapFileValid;
  150.   END;
  151.  
  152.  
  153. PROCEDURE DoneSwapManager;
  154.   BEGIN
  155.  
  156.     WHILE HandleListHead <> NIL DO
  157.       HandleListHead^.Done;
  158.  
  159.     Dispose(SwapFile, Done);
  160.     SwapFile       := NIL;
  161.     HandleListHead := NIL;
  162.     HandleListTail := NIL;
  163.  
  164.   END;
  165.  
  166.  
  167.  
  168.  
  169. {----------------------------------------------------------------------------}
  170. { TSwapHandle.                                                                           }
  171. {____________________________________________________________________________}
  172.  
  173. CONSTRUCTOR TSwapHandle.Init;
  174.   BEGIN
  175.     Status := stOk;
  176.     Size   := 0;
  177.  
  178.     Link;
  179.   END;
  180.  
  181.  
  182. DESTRUCTOR TSwapHandle.Done;
  183.   BEGIN
  184.     UnLink;
  185.  
  186.     Pos    := 0;
  187.     Size   := 0;
  188.     Status := stOk;
  189.   END;
  190.  
  191.  
  192. PROCEDURE TSwapHandle.Error ( AStatus: WORD );
  193.   BEGIN
  194.     Status := AStatus;
  195.   END;
  196.  
  197.  
  198. PROCEDURE TSwapHandle.Link;
  199.   VAR
  200.     p : PSwapHandle;
  201.   BEGIN
  202.     IF Size = 0 THEN
  203.       BEGIN
  204.         Unlink;
  205.         EXIT;
  206.       END;
  207.  
  208.     p := HandleListHead;
  209.  
  210.     IF (p = NIL) OR (p^.Pos >= Size) THEN
  211.       BEGIN
  212.         UnLink;
  213.  
  214.         Pos        := 0;
  215.         Next       := HandleListHead;
  216.         Prev       := NIL;
  217.  
  218.         IF HandleListHead <> NIL THEN
  219.           HandleListHead^.Prev := @Self;
  220.         IF HandleListTail = NIL THEN
  221.           HandleListTail := @Self;
  222.  
  223.         HandleListHead := @Self;
  224.  
  225.         EXIT;
  226.       END;
  227.  
  228.  
  229.     WHILE (p <> NIL) AND (p^.Next <> NIL) AND (p <> @Self)
  230.     AND   (p^.Next^.Pos - p^.Pos - p^.Size < Size) DO
  231.       p := p^.Next;
  232.  
  233.     IF p = @Self THEN EXIT;
  234.  
  235.     UnLink;
  236.  
  237.     Pos     := p^.Pos + p^.Size;
  238.     Next    := p^.Next;
  239.     Prev    := p;
  240.  
  241.     IF Next <> NIL THEN
  242.       Next^.Prev := @Self
  243.     ELSE
  244.       HandleListTail := @Self;
  245.  
  246.     p^.Next := @Self;
  247.   END;
  248.  
  249.  
  250. PROCEDURE TSwapHandle.UnLink;
  251.   VAR
  252.     p : PSwapHandle;
  253.   BEGIN
  254.     p := HandleListHead;
  255.  
  256.     WHILE (p <> NIL) AND (p <> @Self) DO
  257.       p := p^.Next;
  258.  
  259.     IF p = @Self THEN
  260.       BEGIN
  261.  
  262.         IF Prev <> NIL THEN
  263.           Prev^.Next := Next
  264.         ELSE
  265.           HandleListHead := Next;
  266.  
  267.         IF Next <> NIL THEN
  268.           Next^.Prev := Prev
  269.         ELSE
  270.           BEGIN
  271.             HandleListTail := Prev;
  272.           END;
  273.  
  274.       END;
  275.  
  276.     Next   := NIL;
  277.     Prev   := NIL;
  278.   END;
  279.  
  280.  
  281.  
  282. PROCEDURE TSwapHandle.Shrink;
  283.   VAR
  284.     LPos : LONGINT;
  285.   BEGIN
  286.     IF HandleListTail = NIL THEN
  287.       LPos := 0
  288.     ELSE
  289.       LPos := HandleListTail^.Pos + HandleListTail^.Size;
  290.  
  291.     SwapFile^.Reset;
  292.     SwapFile^.Seek(LPos);
  293.     SwapFile^.Reset;
  294.     SwapFile^.Truncate;
  295.     SwapFile^.Reset;
  296.   END;
  297.  
  298.  
  299. PROCEDURE TSwapHandle.Free;
  300.   BEGIN
  301.     Size := 0;
  302.     UnLink;
  303.  
  304.     CASE NeedCleanup OF
  305.       cluFast: FastCleanup;
  306.       cluFull: FullCleanup;
  307.     END;
  308.   END;
  309.  
  310.  
  311. FUNCTION TSwapHandle.Write ( VAR Buf; ASize: WORD ) : BOOLEAN;
  312.   VAR
  313.     f : TClAction;
  314.   BEGIN
  315.     Status := 0;
  316.     Size   := ASize;
  317.  
  318.     IF ASize = 0 THEN EXIT;
  319.  
  320.     UnLink;
  321.     Link;
  322.     f := NeedCleanup;
  323.     IF f <> cluNone THEN
  324.       BEGIN
  325.         UnLink;
  326.         CASE f OF
  327.           cluFast: FastCleanup;
  328.           cluFull: FullCleanup;
  329.         END;
  330.         Link;
  331.       END;
  332.  
  333.     SwapFile^.Reset;
  334.     SwapFile^.Seek(Pos);
  335.     SwapFile^.Reset;
  336.     SwapFile^.Write(Buf, ASize);
  337.     Status := SwapFile^.Status;
  338.     IF Status <> stOk THEN
  339.       Error(Status);
  340.     SwapFile^.Reset;
  341.   END;
  342.  
  343.  
  344. FUNCTION TSwapHandle.Read ( VAR Buf; ASize: WORD ) : BOOLEAN;
  345.   BEGIN
  346.     Status := 0;
  347.  
  348.     IF Size < ASize THEN
  349.       ASize := Size;
  350.  
  351.     SwapFile^.Reset;
  352.     SwapFile^.Seek(Pos);
  353.     SwapFile^.Reset;
  354.     SwapFile^.Read(Buf, ASize);
  355.     Status := SwapFile^.Status;
  356.     IF Status <> stOk THEN
  357.       Error(Status);
  358.     SwapFile^.Reset;
  359.  
  360.     IF Status <> stOk THEN
  361.       FillChar(Buf, ASize, 0);
  362.   END;
  363.  
  364.  
  365. PROCEDURE TSwapHandle.MoveFrom(OPos: LONGINT);
  366.   VAR
  367.     Buf   : POINTER;
  368.     BSize : WORD;
  369.     TSize : WORD;
  370.     OSize : WORD;
  371.     pos1  : LONGINT;
  372.     pos2  : LONGINT;
  373.   BEGIN
  374.     IF Size = 0 THEN EXIT;
  375.  
  376.     IF MaxAvail > 65520 THEN
  377.       BSize := 65520
  378.     ELSE
  379.       BSize := MaxAvail;
  380.  
  381.     IF BSize > Size THEN BSize := Size;
  382.  
  383.     FullHeap.HGetMem(Buf, BSize);
  384.  
  385.     pos1 := OPos;
  386.     pos2 := Pos;
  387.  
  388.     TSize := Size;
  389.  
  390.     WHILE TSize > 0 DO
  391.       BEGIN
  392.         OSize := TSize;
  393.         IF OSize > BSize THEN
  394.           OSize := BSize;
  395.  
  396.         SwapFile^.Reset;
  397.         SwapFile^.Seek(pos1);
  398.         SwapFile^.Reset;
  399.         SwapFile^.Read(Buf^, OSize);
  400.         SwapFile^.Reset;
  401.         SwapFile^.Seek(pos2);
  402.         SwapFile^.Reset;
  403.         SwapFile^.Write(Buf^, OSize);
  404.         INC(pos1, OSize);
  405.         INC(pos2, OSize);
  406.  
  407.         DEC(TSize, OSize);
  408.       END;
  409.  
  410.     SwapFile^.Reset;
  411.     FullHeap.HFreeMem(Buf, BSize);
  412.   END;
  413.  
  414.  
  415. FUNCTION TSwapHandle.NeedCleanup : TClAction;
  416.   VAR
  417.     PCent : LONGINT;
  418.     TS    : LONGINT;
  419.   BEGIN
  420.     TS := TotalSize;
  421.     IF TS > 0 THEN
  422.       PCent := UnusedMem * 100 DIV TS
  423.     ELSE
  424.       PCent := 0;
  425.  
  426.     IF PCent > 35 THEN
  427.       NeedCleanup := cluFull
  428.     ELSE IF PCent > 10 THEN
  429.       NeedCleanup := cluFast
  430.     ELSE
  431.       NeedCleanup := cluNone;
  432.   END;
  433.  
  434.  
  435. PROCEDURE TSwapHandle.FastCleanup;
  436.   VAR
  437.     p    : PSwapHandle;
  438.     q    : PSwapHandle;
  439.     OPos : LONGINT;
  440.   BEGIN
  441.     p := HandleListTail;
  442.  
  443.     WHILE (p <> NIL) AND (p^.Pos > 0) DO
  444.       BEGIN
  445.  
  446.         q := p^.Prev;
  447.         OPos := p^.Pos;
  448.         p^.Link;
  449.         IF p^.Pos <> OPos THEN
  450.           p^.MoveFrom(OPos);
  451.  
  452.         p := q;
  453.  
  454.       END;
  455.  
  456.     Shrink;
  457.   END;
  458.  
  459.  
  460. PROCEDURE TSwapHandle.FullCleanup;
  461.   VAR
  462.     p    : PSwapHandle;
  463.     q    : PSwapHandle;
  464.     OPos : LONGINT;
  465.   BEGIN
  466.     p := HandleListHead;
  467.  
  468.     WHILE p <> NIL DO
  469.       BEGIN
  470.  
  471.         q := p^.Next;
  472.  
  473.         OPos := p^.Pos;
  474.         p^.Unlink;
  475.         p^.Link;
  476.         IF p^.Pos <> OPos THEN
  477.           p^.MoveFrom(OPos);
  478.  
  479.         p := q;
  480.  
  481.       END;
  482.  
  483.     Shrink;
  484.   END;
  485.  
  486.  
  487. FUNCTION TSwapHandle.UsedMem : LONGINT;
  488.   VAR
  489.     p : PSwapHandle;
  490.     l : LONGINT;
  491.   BEGIN
  492.     p := HandleListHead;
  493.     l := 0;
  494.     WHILE p <> NIL DO
  495.       BEGIN
  496.         INC(l, p^.Size);
  497.         p := p^.Next;
  498.       END;
  499.  
  500.     UsedMem := l;
  501.   END;
  502.  
  503.  
  504. FUNCTION TSwapHandle.UnusedMem : LONGINT;
  505.   BEGIN
  506.     UnusedMem := TotalSize - UsedMem;
  507.   END;
  508.  
  509.  
  510. FUNCTION TSwapHandle.TotalSize : LONGINT;
  511.   BEGIN
  512.     SwapFile^.Reset;
  513.     TotalSize := SwapFile^.GetSize;
  514.   END;
  515.  
  516.  
  517.  
  518.  
  519. END.